package spring.cloud.tasks.api.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import spring.cloud.tasks.api.analyzer.StatisticsRefreshService;
import spring.cloud.tasks.api.database.entity.ZooKeeperClusterDto;
import spring.cloud.tasks.api.database.service.NameSpaceZooKeeperClusterMappingDtoService;
import spring.cloud.tasks.api.database.service.ZooKeeperClusterDtoService;
import spring.cloud.tasks.api.domain.different_info.TaskDifferentInfo;
import spring.cloud.tasks.api.domain.zooKeeperClusterAndNameSpace.ZooKeeperCluster;
import spring.cloud.tasks.api.service.UtilsService;
import spring.cloud.tasks.api.service.ZooKeeperClusterService;
import spring.cloud.tasks.api.service.ZooKeeperDatabaseTaskDifferentInfoService;
import spring.cloud.tasks.api.utils.Response;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping("/utils")
public class UtilsController {

    @Resource
    private UtilsService utilsService;
    @Resource
    private ZooKeeperClusterService zooKeeperService;
    @Resource
    private ZooKeeperClusterDtoService zooKeeperClusterInfoService;
    @Resource
    private NameSpaceZooKeeperClusterMappingDtoService nameSpaceZooKeeperClusterMapping4SqlService;
    @Resource
    private StatisticsRefreshService statisticsRefreshService;
    @Resource
    private ZooKeeperDatabaseTaskDifferentInfoService zooKeeperDatabaseTaskDifferentInfoService;


    @RequestMapping(value = "/checkAndForecastCron")
    public Response checkAndForecastCron(@RequestParam String cronExpressionString, String pauseDatePeriod, String pauseTimePeriod) throws RuntimeException {
        return Response.success(utilsService.checkAndForecastCron(cronExpressionString, pauseDatePeriod, pauseTimePeriod));
    }


    @RequestMapping(value = "/getZooKeeperClusterList")
    public Response getZooKeeperClusterList() {
        List<ZooKeeperCluster> zooKeeperServiceZooKeeperClusterList = zooKeeperService.getZooKeeperClusterList();
        List<String> list = new ArrayList<String>();
        for (ZooKeeperCluster zooKeeperCluster : zooKeeperServiceZooKeeperClusterList) {
            list.add(zooKeeperCluster.getZooKeeperClusterKey());
        }
        return Response.success(list);
    }

    /**
     * 发现nameSpace相关注册信息.
     */

    @RequestMapping(value = "/discover", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity discover(String nameSpace) throws RuntimeException {
        Map<String, String> response = new HashMap<>(2);
        response.put("connectString", getConnectString(nameSpace));
        return ResponseEntity.ok(response);
    }

    /**
     * 返回ZK连接串
     */
    private String getConnectString(String nameSpace) throws RuntimeException {
        if (StringUtils.isBlank(nameSpace)) {
            throw new RuntimeException(String.format("nameSpace"));
        }
        String zooKeeperClusterKey = nameSpaceZooKeeperClusterMapping4SqlService.getZooKeeperClusterKey(nameSpace);
        if (zooKeeperClusterKey == null) {
            throw new RuntimeException("The nameSpace：[" + nameSpace + "] is not registered in Saturn.");
        }
        ZooKeeperClusterDto zooKeeperClusterInfo = zooKeeperClusterInfoService.selectByZooKeeperClusterKey(zooKeeperClusterKey);
        if (zooKeeperClusterInfo == null) {
            throw new RuntimeException("The clusterKey: [" + zooKeeperClusterKey + "] is not configured in db for " + nameSpace);
        }
        return zooKeeperClusterInfo.getZooKeeperClusterAddressList();
    }

    /**
     * 根据ZK集群key，刷新该集群的dashboard信息
     */
    //@Audit(type = AuditType.REST)
    @RequestMapping(value = "/statistics/refresh", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Object> dashboardRefresh(String zooKeeperClusterKey, HttpServletRequest request) throws RuntimeException {
        try {

            long beforeRefresh = System.currentTimeMillis();
            statisticsRefreshService.refresh(zooKeeperClusterKey);
            long afterRefresh = System.currentTimeMillis();
            long takeTime = afterRefresh - beforeRefresh;
            return new ResponseEntity<Object>(takeTime, HttpStatus.OK);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }


    @RequestMapping(value = "/differentByZooKeeperCluster", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public ResponseEntity<Object> differentByZooKeeperCluster(String zooKeeperClusterKey, HttpServletRequest request)
            throws RuntimeException {
        try {

            List<TaskDifferentInfo> differentInfoList = zooKeeperDatabaseTaskDifferentInfoService.differentByZooKeeperClusterKey(zooKeeperClusterKey);
            return new ResponseEntity<Object>(differentInfoList, HttpStatus.OK);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

}
